import queue
import subprocess
import threading
import requests
import docker
import json
import os

# 定义全局任务队列
task_queue = queue.Queue()

# 定义任务状态存储
task_status = {}


def add_task(task_id, task_data):
    """
    添加任务到队列，并初始化任务状态。
    """
    if task_id in task_status:
        return {"error": "Task ID already exists"}

    # 初始化任务状态
    task_status[task_id] = {
        "status": "pending",
        "progress": 0,
        "error_message": None,
        "result_path": None
    }

    # 将任务添加到队列
    task_queue.put({"task_id": task_id, "task_data": task_data})
    return {"message": "Task added", "task_id": task_id}


def process_task():
    """
    从任务队列中取出任务，依次处理。
    """
    while True:
        try:
            task = task_queue.get(timeout=1)
            task_id = task["task_id"]
            task_data = task["task_data"]

            try:
                print(f"\n开始处理任务: {task_id}")
                print(f"任务参数: {task_data}")

                # 更新状态为处理中
                task_status[task_id]["status"] = "processing"
                task_status[task_id]["progress"] = 0
                print(f"任务状态已更新为: processing")

                # 构造命令
                # command = f'D:/UAV_exe/uav.exe --image_dir {task_data["image_dir"]} ' \
                #     f'--output_dir {task_data["output_path"]} ' \
                #     f'--mode {task_data["mode"]}'
                # command = f"docker run --rm -v {task_data['image_dir']}:/datasets -v {task_data['output_path']}:/output uav_docker --image_dir /datasets --output_dir /output/result --mode {task_data['mode']}"
                # print(f"执行命令: {command}")
                #
                # # 调用命令行执行三维重建
                # print("开始执行三维重建...")
                # process = subprocess.run(
                #     command, shell=True, text=True, encoding="utf-8", stdout=subprocess.PIPE, stderr=subprocess.PIPE)

                client = docker.from_env()

                volumes = {
                    task_data['image_dir']: {'bind': '/datasets', 'mode': 'ro'},
                    task_data['output_path']: {'bind': '/output', 'mode': 'rw'}
                }

                command = [
                    '--image_dir', '/datasets',
                    '--output_dir', '/output/result',
                    '--mode', task_data['mode']
                ]

                print(
                    f"执行命令: docker run --rm -v {task_data['image_dir']}:/datasets -v {task_data['output_path']}:/output uav_docker {' '.join(command)}")
                print("开始执行三维重建...")

                error_message = ''
                container = None
                try:
                    # 启动并运行容器
                    container = client.containers.create(
                        image='uav_docker',
                        command=command,
                        volumes=volumes,
                        detach=True  # 一定要 True，才能手动 start
                    )
                    container.start()
                    exit_status = container.wait()
                    return_code = exit_status.get('StatusCode', -1)
                    logs = container.logs(tail=50).decode('utf-8')
                    print(logs)
                    success = True

                except docker.errors.ContainerError as e:
                    print(f"容器运行失败，错误码: {e.exit_status}, 错误输出: {e.stderr.decode('utf-8')}")
                    success = False
                    error_message = e.stderr.decode('utf-8')
                except Exception as e:
                    print(f"执行异常 {e}")
                finally:
                    try:
                        container.remove(force=True)
                    except Exception:
                        pass  # 避免因remove失败导致程序崩溃

                status_data = {
                    "mode": 3 if task_data["mode"] == "三维模式" else 2,
                    "prod": task_id,
                    "status": "1" if success else "2"
                }
                # 更新状态
                if success:
                    print("任务执行成功")
                    task_status[task_id]["status"] = "completed"
                    task_status[task_id]["progress"] = 100
                    task_status[task_id]["result_path"] = task_data["output_path"]
                else:
                    print("任务执行失败")
                    task_status[task_id]["status"] = "failed"
                    task_status[task_id]["error_message"] = error_message

                print(f"准备发送状态更新: {status_data}")
                # 发送POST请求更新状态
                response = requests.post(
                    "http://localhost:18080/api/uav/status",
                    json=status_data,
                    headers={"Content-Type": "application/json"}
                )
                print(f"状态更新响应: {response.status_code} - {response.text}")

            except Exception as e:
                print(f"处理任务时发生异常: {str(e)}")
                # 发生异常时也需要通知状态更新
                try:
                    status_data = {
                        "mode": 3 if task_data["mode"] == "三维模式" else 2,
                        "prod": task_id,
                        "status": "2"  # 失败状态
                    }
                    print(f"发送失败状态更新: {status_data}")
                    requests.post(
                        "http://localhost:18080/api/uav/status",
                        json=status_data,
                        headers={"Content-Type": "application/json"}
                    )
                except Exception as post_error:
                    print(f"发送状态更新失败: {str(post_error)}")

                task_status[task_id]["status"] = "failed"
                task_status[task_id]["error_message"] = str(e)
            finally:
                print(f"任务 {task_id} 处理完成\n")
                task_queue.task_done()

        except queue.Empty:
            continue  # 队列为空时继续等待
        except Exception as e:
            print(f"任务处理主循环发生异常: {str(e)}")


# 启动后台线程执行任务
worker_thread = threading.Thread(target=process_task, daemon=True)
worker_thread.start()
